(in-package clim-user)

(define-application-frame word		;name
     ()					;superclasses
  ((current-file				;slots
    :accessor current-file
    :initarg :current-file))
   ;; :panes option
   (:panes
   ;; pane description
    (title				;pane name 
     :application			;pane type
     ;; pane options
     :display-function #'display-current-file
     :initial-cursor-visibility nil)
   ;; pane description
    (document				;pane name 
     :application			;pane type
     :display-function #'display-document))
   ;; :layouts option
   (:layouts
    (default				;name of the layout
	(vertically ()			;layout macros
	  (1/5 title)
	  (4/5 document)))))

(defmethod display-current-file ((frame word) stream)
  (draw-text* stream "Document:" 10 15)
  (if (slot-boundp frame 'current-file)
      (draw-text* stream (current-file frame) 20 40)
      (draw-text* stream "Untitled" 20 40)))


;;; utilities

(defun line-height (frame pane-name)
  "Return the line height of the default text style for pane-name."
  (text-style-height *default-text-style* (get-frame-pane frame pane-name)))

(defmacro do-file ((path line-variable &key (key #'identity)) &body body)
  "Iterate over the lines of the file, binding the line to the line-variable
in each iterateion"
  (let ((str (gensym))
	(var (gensym)))
    `(with-open-file (,str ,path :direction :input)
       (do ((,var (read-line ,str nil)
		  (read-line ,str nil)))
	   ((not ,var))
	 (let ((,line-variable (funcall ,key ,var)))
	   ,@body)))))

;; document display

(defmethod display-document ((frame word) stream)
  (when (slot-boundp frame 'current-file)
    (let ((height-so-far 5))
      (do-file ((current-file frame) line)
	(draw-text* stream line 5 height-so-far)
	(incf height-so-far (line-height frame 'document)))
      #+nil (draw-rectangle* stream 5 5 20 height-so-far))))

;; test

(run-frame-top-level
 (make-application-frame 'word 
			 :height 300
			 :width 300
			 :current-file "word.lisp"))